package cn.raven.user.service.impl;

import cn.raven.basic.constant.BaseConstant;
import cn.raven.basic.dto.EmailRegisterDto;
import cn.raven.basic.dto.VerifyRegisterDto;
import cn.raven.basic.exception.BusinessException;
import cn.raven.basic.utils.MD5Utils;
import cn.raven.basic.utils.StrUtils;
import cn.raven.org.domain.Employee;
import cn.raven.user.domain.Logininfo;
import cn.raven.user.domain.User;
import cn.raven.user.mapper.LogininfoMapper;
import cn.raven.user.mapper.UserMapper;
import cn.raven.user.service.IUserService;
import cn.raven.basic.service.impl.BaseServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author Raven
 * @since 2022-07-06
 */
@Service
public class UserServiceImpl extends BaseServiceImpl<User> implements IUserService {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private LogininfoMapper logininfoMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    
    /** 
    * @Title: register
    * @Description: 手机注册
    * @Author: king
    * @Version: 1.0
    * @Date:  2022/7/6 15:47  
    * @Parameters: [verifyRegisterDto]
    * @Return void
      */
    @Override
    public void register(VerifyRegisterDto verifyRegisterDto) {
        String phone = verifyRegisterDto.getPhone();
        String password = verifyRegisterDto.getPassword();
        String confirmPassword = verifyRegisterDto.getConfirmPassword();
        String phoneCode = verifyRegisterDto.getPhoneCode();
        String imageCodeKey = verifyRegisterDto.getImageCodeKey();
        String imageCodeValue = verifyRegisterDto.getImageCodeValue();
        //非空
        if(StringUtils.isEmpty(phone) ||
                StringUtils.isEmpty(password) ||
                StringUtils.isEmpty(confirmPassword) ||
                StringUtils.isEmpty(phoneCode)){
            throw new BusinessException("必要信息不能为空");
        }
        //图形验证码是否一致
        Object imageCode = redisTemplate.opsForValue().get(imageCodeKey);
        if (!imageCode.toString().equalsIgnoreCase(imageCodeValue)){
            throw new BusinessException("图形验证码错误");
        }
        //短信验证码
        String phoneCodeKey = BaseConstant.BusinessConstant.SMS_REGISTER_CODE+phone;
        Object phoneCodeValue = redisTemplate.opsForValue().get(phoneCodeKey);

        if (phoneCodeValue == null){
            throw new BusinessException("验证码已过期,请重新获取");
        }
        String phoneCodeRedis = phoneCodeValue.toString().split(":")[1];
        if (!phoneCodeRedis.equalsIgnoreCase(phoneCode)){
            throw new BusinessException("验证码错误,请输入正确的验证码");
        }
        //手机号是否注册
        User user = userMapper.findByPhone(phone);
        if (user != null){
            throw new BusinessException("手机号已被注册,请直接登录");
        }
        //给user初始化
        user = register2User(verifyRegisterDto);
        //给logininfo赋值
        Logininfo logininfo = user2Logininfo(user);
        logininfoMapper.add(logininfo);
        user.setLogininfoId(logininfo.getId());
        userMapper.add(user);

    }

    /**
    * @Title: email
    * @Description: 邮箱注册
    * @Author: king
    * @Version: 1.0
    * @Date:  2022/7/7 18:26
    * @Parameters: [emailRegisterDto]
    * @Return void
      */
    @Override
    public void email(EmailRegisterDto emailRegisterDto) {
        String email = emailRegisterDto.getEmail();
        String password = emailRegisterDto.getPassword();
        String confirmPassword = emailRegisterDto.getConfirmPassword();
        //非空
        if (StringUtils.isEmpty(email) ||
                StringUtils.isEmpty(email) ||
                StringUtils.isEmpty(email)){
            throw new BusinessException("参数不能为空");
        }
        User user = userMapper.findByEmail(email);
        if (user !=null){
            throw new BusinessException("邮箱已存在,请直接登录");
        }
        //校验密码是否一致
        if (!password.equals(confirmPassword)){
            throw new BusinessException("密码不一致,请重新输入");
        }
        //初始化user表
        user = emailRegister2User(emailRegisterDto);
        //将user copy给 logininfo
        Logininfo logininfo = user2Logininfo(user);
        logininfoMapper.add(logininfo);
        user.setLogininfoId(logininfo.getId());
        userMapper.add(user);


    }
    /**
    * @Title: loginOut
    * @Description: 登出
    * @Author: king
    * @Version: 1.0
    * @Date:  2022/7/8 11:12
    * @Parameters: [request]
    * @Return void
      */
    @Override
    public void loginOut(HttpServletRequest request) {
        String token = request.getHeader("token");
        redisTemplate.delete(token);
    }

    @Override
    public User findByLogininfoId(Long id) {
       return userMapper.findByLogininfoId(id);
    }

    /**
    * @Title: emailRegister2User
    * @Description: 邮箱登录初始化user
    * @Author: king
    * @Version: 1.0
    * @Date:  2022/7/10 17:43
    * @Parameters: [emailRegisterDto]
    * @Return cn.raven.user.domain.User
      */
    private User emailRegister2User(EmailRegisterDto emailRegisterDto) {
        User user = new User();
        user.setUsername(emailRegisterDto.getEmail());
        user.setPhone(emailRegisterDto.getEmail());
        user.setEmail(emailRegisterDto.getEmail());
        String salt = StrUtils.getComplexRandomString(32);
        String saltPassword = MD5Utils.encrypByMd5(salt + emailRegisterDto.getPassword());
        user.setSalt(salt);
        user.setPassword(saltPassword);
        return user;
    }

    /**
    * @Title: register2User
    * @Description: 给user赋值
    * @Author: king
    * @Version: 1.0
    * @Date:  2022/7/6 15:45  
    * @Parameters: [verifyRegisterDto]
    * @Return cn.raven.user.domain.User
      */
    private User register2User(VerifyRegisterDto verifyRegisterDto) {
        User user = new User();
        String phone = verifyRegisterDto.getPhone();
        user.setUsername(phone);
        user.setPhone(phone);
        String salt = StrUtils.getComplexRandomString(32);
        String saltPassword = MD5Utils.encrypByMd5(salt + verifyRegisterDto.getPassword());
        user.setSalt(salt);
        user.setPassword(saltPassword);
        return user;
    }
    /** 
    * @Title: user2Logininfo
    * @Description: 给logininfo赋值
    * @Author: king
    * @Version: 1.0
    * @Date:  2022/7/6 15:45  
    * @Parameters: [user]
    * @Return cn.raven.user.domain.Logininfo
      */
    private Logininfo user2Logininfo(User user) {
        Logininfo logininfo = new Logininfo();
        BeanUtils.copyProperties(user,logininfo);
        logininfo.setType(1);
        logininfo.setId(user.getLogininfoId());
        return logininfo;
    }

    @Override
    public void add(User user) {
        // 1.初始化emplpyee，并保存，这是引用传递
        initUser(user);
        userMapper.add(user);
        // 2.初始化logininfo，并保存
        Logininfo logininfo = user2Logininfo(user);
        logininfoMapper.add(logininfo);
        // 3.将logininfo的主键Id设置到employee的外键，并修改
        user.setLogininfoId(logininfo.getId());
        userMapper.update(user);
    }

    private void initUser(User user) {
        String salt = StrUtils.getComplexRandomString(32);
        String saltPassword = MD5Utils.encrypByMd5(salt + user.getPassword());
        user.setSalt(salt);
        user.setPassword(saltPassword);
    }
    /** 
    * @Title: update
    * @Description: 级联修改
    * @Author: king
    * @Version: 1.0
    * @Date:  2022/7/6 19:11
    * @Parameters: [user]
    * @Return void
      */
    @Override
    public void update(User user) {
        initUser(user);
        Logininfo logininfo = user2Logininfo(user);
        logininfoMapper.update(logininfo);
        userMapper.update(user);
    }

    @Override
    public void del(Long id) {
        User user = userMapper.findOne(id);
        userMapper.del(id);
        logininfoMapper.del(user.getLogininfoId());
    }
}
